package gitee

import (
	"errors"
	"fmt"
	"os"
	"strings"
	"time"

	"gitee.com/StarCitizen_CN/logger"
	git "github.com/go-git/go-git/v5"
	gitconfig "github.com/go-git/go-git/v5/config"
)

func parseGiteeHttpUrlRepo(repoAddress string) (string, string) {
	address := strings.Split(repoAddress, "/")
	repoName := address[len(address)-1]
	repoOwner := address[len(address)-2]

	return repoOwner, repoName
}

func parseGiteeTime(date string) (time.Time, error) {
	return time.Parse("2006-01-02T15:04:05+08:00", date)
}

func FetchByGit(repoRemoteAddress string, repoDir string) (err error) {

	_, err = git.PlainClone(repoDir, false, &git.CloneOptions{
		URL:      repoRemoteAddress,
		Progress: os.Stdout,
	})

	if errors.Is(err, git.ErrRepositoryAlreadyExists) {
		err = nil
	}
	if err != nil {
		err = fmt.Errorf("git: PlainClone \n%w", err)
		logger.Err(err)
	}

	repo, plainOpenErr := git.PlainOpen(repoDir)
	if plainOpenErr != nil {
		err = fmt.Errorf("git: PlainOpen \n%w", plainOpenErr)
		logger.Err(err)
		return err
	}

	remote, remoteErr := repo.Remote("origin")
	if remoteErr != nil {
		err = fmt.Errorf("git: Remote \n%w", remoteErr)
		logger.Err(err)
		return err
	}

	for _, add := range remote.Config().URLs {
		if repoRemoteAddress != add {
			logger.Debug(repoRemoteAddress + "\tvs\t" + add)
			repo.DeleteRemote("origin")
			repo.CreateRemote(&gitconfig.RemoteConfig{
				Name: "origin",
				URLs: []string{repoRemoteAddress},
			})

			return FetchByGit(repoRemoteAddress, repoDir)
		}
	}

	fetchErr := repo.Fetch(&git.FetchOptions{})
	if errors.Is(fetchErr, git.NoErrAlreadyUpToDate) {
		logger.Err(fmt.Errorf("git: Fetch  \n%w", fetchErr))
		fetchErr = nil
	}
	if fetchErr != nil {
		err = fmt.Errorf("git: Fetch \n%w", err)
		logger.Err(err)
		return err
	}

	wtree, err := repo.Worktree()
	if err != nil {
		err = fmt.Errorf("git: Worktree \n%w", err)
		logger.Err(err)
		return err
	}

	err = wtree.Reset(&git.ResetOptions{
		Mode: git.HardReset,
	})
	if err != nil {
		err = fmt.Errorf("git: Reset \n%w", err)
		logger.Err(err)
		return err
	}

	// err = wtree.Checkout(&git.CheckoutOptions{
	// 	Branch: plumbing.Master,
	// 	Force:  true,
	// })
	// if err != nil {
	// 	err = fmt.Errorf("git: Checkout \n%w", err)
	// 	logger.Err(err)
	// 	return err
	// }

	err = wtree.Pull(
		&git.PullOptions{},
	)
	if errors.Is(err, git.NoErrAlreadyUpToDate) {
		err = nil
	}
	if err != nil {
		err = fmt.Errorf("git: Pull \n%w", err)
		logger.Err(err)
		return err
	}

	return
}
